﻿using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Kugar.Core.ExtMethod;
using Kugar.Core.Web;
using Kugar.UI.Web.AdminLTE.Interfaces;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Kugar.UI.Web.AdminLTE.Authentications
{
    public class AdminLteAuthenticationHandler: CookieAuthenticationHandler<AdminLteAuthenticationOptions>
    {
        public AdminLteAuthenticationHandler(IOptionsMonitor<AdminLteAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
        {

        }
    }


    

    public class AdminLteAuthenticationOptions : CookieAuthenticationOptions
    {
        private string _schemeName = "default";
        private string _mainTitle = "";
        private string _subTitle = "";
        private string _logoUrl = $"{AdminLTEUI.LayoutPath.ResourceBaseUrl}/Content/images/login_logo.png";
        private string _regisgerTitle = "注册新用户";
        private string _registerUrl = "";
        private string _forgetpasswordTitle  = "忘记密码";
        private string _forgetpasswordUrl = "";
        private IAdminLoginManager _login = null;
        private string _prefixTitle = "";
        private ILoginPageManager _loginPageManager = null;
        private string _defaultUserID = "";

        public AdminLteAuthenticationOptions():base()
        {
            this.Events.OnValidatePrincipal = OnValidate;
            //this.Events.OnRedirectToLogin= OnRedirectToLogin;
            this.ReturnUrlParameter = "backurl";
            this.SlidingExpiration = true;
            this.ExpireTimeSpan=TimeSpan.FromDays(5);

            refreshSetting();
        }

        //private Task OnRedirectToLogin(RedirectContext<CookieAuthenticationOptions> arg)
        //{
        //    //throw new NotImplementedException();

        //    return Task.CompletedTask;
        //}

        public IAdminLoginManager LoginManager
        {
            set
            {
                _login = value;
                refreshSetting();
            }
            get => _login;
        }

        /// <summary>
        /// 用于区分不同后台,如平台后台,客户后台等
        /// </summary>
        public string SchemeName
        {
            set
            {
                _schemeName = value;
                
                refreshSetting();
            }
            get { return _schemeName; }
        }

        /// <summary>
        /// 管理后台显示的Logo
        /// </summary>
        public string LogoUrl
        {
            set
            {
                _logoUrl = value;
                refreshSetting();
            }
            get => _logoUrl;
        }

        /// <summary>
        /// 管理后台显示的标题
        /// </summary>
        public string MainTitle
        {
            set
            {
                _mainTitle = value;
                refreshSetting();
            }
            get => _mainTitle;
        }

        /// <summary>
        /// 子标题
        /// </summary>
        public string SubTitle
        {
            set {
                _subTitle = value;
                refreshSetting();
            }
            get => _subTitle;
        }

        /// <summary>
        /// 标题前缀
        /// </summary>
        public string PrefixTitle
        {
            set
            {
                _prefixTitle = value;
                refreshSetting();
            }
            get => _prefixTitle;
        }

        /// <summary>
        /// 登录页管理接口,可以不设置
        /// </summary>
        public ILoginPageManager loginPageManager
        {
            get => _loginPageManager;
            set
            {
                _loginPageManager = value;
                refreshSetting();
            }
        }

        /// <summary>
        /// 注册用户按钮标题
        /// </summary>
        public string RegisterTitle
        {
            set
            {
                _regisgerTitle = value;
                refreshSetting();
            }
            get => _regisgerTitle;
        }

        /// <summary>
        /// 注册用户地址链接
        /// </summary>
        public string RegisterUrl
        {
            set
            {
                _registerUrl = value;
                refreshSetting();
            }
            get => _registerUrl;
        }

        /// <summary>
        /// 忘记密码按钮标题
        /// </summary>
        public string ForgetpasswordTitle
        {
            set
            {
                _forgetpasswordTitle = value;
                refreshSetting();
            }
            get => _forgetpasswordTitle;
        }

        /// <summary>
        /// 忘记密码按钮的跳转链接
        /// </summary>
        public string ForgetpasswordUrl
        {
            set
            {
                _forgetpasswordUrl = value;
                refreshSetting();
            }
            get => _forgetpasswordUrl;
        }

        /// <summary>
        /// 默认用户ID
        /// </summary>
        public string DefaultUserID
        {
            set
            {
                _defaultUserID = value;
                refreshSetting();
            }
            get => _defaultUserID;
        }
        
        private async Task OnValidate(CookieValidatePrincipalContext context)
        {
            if (!string.IsNullOrEmpty(_defaultUserID))
            {
                context.Principal.AddClaim("UserID", _defaultUserID, "string");
            }
            else
            {
                var userName = context.Principal.FindFirst("UserName")?.Value;
                var pw = context.Principal.FindFirst("k")?.Value;

                try
                {
                    pw = pw.DesDecrypt(SchemeName.ToLower().MD5_32().MD5_32().Left(8));
                }
                catch (Exception e)
                {
                    context.RejectPrincipal();
                    return;
                }

                var loginManager =
                    (LoginManager ??
                     (IAdminLoginManager)context.HttpContext.RequestServices.GetService(typeof(IAdminLoginManager))) ??
                    throw new ArgumentNullException("不存在IAdminLoginManager接口");


                var ret =await loginManager.Login(context.HttpContext, userName, pw);

                if (ret.IsSuccess)
                {
                    context.Principal.AddClaim("UserID", ret.ReturnData, "string");
                }
                else
                {
                    context.RejectPrincipal();
                    context.Response.Redirect(this.LogoutPath);
                }
            }

            context.HttpContext.GetRouteData().Values.Add("authenticationType", SchemeName);
            context.HttpContext.Items["SchemeName"] = SchemeName;
            context.HttpContext.Items["PrefixTitle"] = PrefixTitle;
        }

        private void refreshSetting()
        {
            var config = GlobalConfiguration.LoginViewSettings.TryGetValue(SchemeName,null);

            if (config==null)
            {
                config=new Dictionary<string, object>();
                GlobalConfiguration.LoginViewSettings.Add(SchemeName,config);
            }

            config["MainTitle"] = MainTitle;
            config["SubTitle"] = SubTitle;
            config["LogoUrl"] = LogoUrl;
            config["RegisterTitle"] = _regisgerTitle;
            config["RegisterUrl"] = _registerUrl;
            config["ForgetpasswordTitle"] = _forgetpasswordTitle;
            config["ForgetpasswordUrl"] = _forgetpasswordUrl;
            config["LoginManager"] = _login;
            config["PrefixTitle"] = _prefixTitle;
            config["LoginPageManager"] = _loginPageManager;
            config["DefaultUserID"] = _defaultUserID;

            this.LoginPath = $"/AdminCore/Login/{_schemeName}";
            this.LogoutPath = $"/AdminCore/Logout/{_schemeName}";
        }
    }
}
